/*
This file is to realize the normal of OLED display and import the library file of each sensor

September-December 2016

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

The latest version of this library can always be found at
https://github.com/DFRobot/DFRobot_BlunoAccessory
*/
#include <BlunoAccessory.h>
#define RES 6
#define DC 7

//To write command the OLED
void Writec(unsigned char COM)
{
     Wire.beginTransmission(0x3C);
     Wire.write((uint8_t)0x00);
     Wire.write(COM);
     Wire.endTransmission();
}
//To write data OLED
void Writed(unsigned char DATA)
{
     Wire.beginTransmission(0x3C);
     Wire.write((uint8_t)0x40);
     Wire.write(DATA);
     Wire.endTransmission();
	 
}
void BlunoAccessory::begin()
{
    pinMode(RES,OUTPUT);//RES
    pinMode(DC,OUTPUT);//D/C#
    //SAO=0
    digitalWrite(DC,LOW);
	Wire.begin();
}
void BlunoAccessory::Reset()
{
	digitalWrite(RES,HIGH);   delay(100);
    digitalWrite(RES,LOW);    delay(100);
    digitalWrite(RES,HIGH);   delay(100);
}
//Initialize the OLED
void BlunoAccessory::SSD1306()
{
     Writec(0XAE);//display off
     Writec(0X00);//set lower column address
     Writec(0X10);//set higher column address
     Writec(0X40);//set display start line
     Writec(0XB0);//set page address
     Writec(0X81);//set contract control
     Writec(0XCF);// VCC Generated by Internal DC/DC Circuit 
     Writec(0XA1);//set segment remap  column address 127 is mapped to SEG0
     Writec(0XA6);//normal / reverse   normal display
     Writec(0XA8);//multiplex ratio
     Writec(0X3F);//1/64
     Writec(0XC8);//Com scan direction remapped mode. Scan from COM[N-1] to COM0 
     Writec(0XD3);//set display offset
     Writec(0X00);
     Writec(0XD5);//set osc division
     Writec(0X80);
     Writec(0XD9);//set pre-charge period
     Writec(0X11);
     Writec(0XDa);//set COM pins
     Writec(0X12);
     Writec(0X8d);/*set charge pump enable*/
     Writec(0X14);
     Writec(0Xdb);//Set VcomH    
     Writec(0X20);    
     Writec(0XAF);//display ON
}
//The OLED screen clearing
void BlunoAccessory::fill(unsigned char dat)
{
     unsigned char i,j;
     Writec(0x00);//set lower column address
     Writec(0x10);//set higher column address
     Writec(0xB0);//set page address
     for(j = 0; j < 8; j++)
     {
         Writec(0xB0 + j);//set page address
         Writec(0x00);//set lower column address
         Writec(0x10);//set higher column address
        for(i = 0; i < 128; i++)
        {
            Writed(dat);
        }
     }
}
void BlunoAccessory::fill(uint8_t x,uint8_t y,unsigned char dat)
{
     unsigned char i,j;
     for(j = 0; j < 2; j++)
     {
         Writec(0xB0 + y);//set page address
         Writec(0x00 + (x/2) + (x%2) * (0x08));//set lower column address
         Writec(0x10 + (x/2) + (x%2) * (0x08));//set higher column address
		 y++;
		 if(x == 9){
			 for(i = 0; i < 49; i++)
              {
                 Writed(dat);
              }
		 }else if(x == 5){
			 for(i = 0; i < 33; i++)
              {
                 Writed(dat);
              }
		 }else if(x == 12){
			 for(i = 0; i < 24; i++)
              {
                 Writed(dat);
              }
		 }else if(x == 0){
			 for(i = 0; i < 128; i++)
              {
                 Writed(dat);
              }
		 }
        
     }
}

#ifdef ARDUINO_ARCH_ARC32
//On the OLED display

void BlunoAccessory::show(uint8_t x, uint8_t y, uint8_t DATA)
{    
    unsigned int i,j;
	for(j = 0; j < 2; j++)
	{
		Writec(0xB0 + y);//set page address
        Writec(0x00 + (x/2) + (x%2) * (0x08));//set lower column address
        Writec(0x10 + (x/2) + (x%2) * (0x08));//set higher column address
		y++;
		for(i = 0; i < 8; i++)
	    {
		   Writed(WordStock[DATA][j * 8 + i]);
	    }
    }
}
#else
void BlunoAccessory::show(uint8_t x, uint8_t y, uint8_t DATA)
{    
    unsigned char WordStock[16];
	register char b;
      for(b = 0; b < 16; b++)
		{
			WordStock[b] = pgm_read_byte(&F8X16[DATA][b]);
		}
    unsigned int i,j;
	for(j = 0; j < 2; j++)
	{
		Writec(0xB0 + y);//set page address
        Writec(0x00 + (x/2) + (x%2) * (0x08));//set lower column address
        Writec(0x10 + (x/2) + (x%2) * (0x08));//set higher column address
		y++;
		for(i = 0; i < 8; i++)
	    {
		   Writed(WordStock[j * 8 + i]);
	    }
    }
}	 	 
#endif
void BlunoAccessory::setCursor(uint8_t x, uint8_t y)
{
	Writec(0xB0 + y);//set page address
    Writec(0x00 + (x/2) + (x%2) * (0x08));//set lower column address
    Writec(0x10 + (x/2) + (x%2) * (0x08));//set higher column address
}

void BlunoAccessory::print(uint8_t x, uint8_t y,float f)
{
	char buf[25];
	char *uint = buf;
	sprintf(buf,"%f",f);
	while (*uint != '\0') {  
      show(x++,y,(*uint++)-' '); 		
    }
}

void BlunoAccessory::print(uint8_t x, uint8_t y,int n)
{
	char buf[25];
	char *uint = buf;
	itoa(n,buf,10);
	while (*uint != '\0') {  
      show(x++,y,(*uint++)-' '); 		
    } 
}

void BlunoAccessory::print(uint8_t x, uint8_t y, const char *str)
{
    while (*str != '\0') {  
        show(x++,y,(*str++)-' '); 		
    } 
}
void BlunoAccessory::print(uint8_t x, uint8_t y, String str)
{
   const char *a;
   a=str.c_str();
   print(x, y, a);
}


class BlunoAccessory blunoAccessory;

